BLANK();
DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
- DEFINE(IA64_CPUINFO_PGD_QUICK_OFFSET, offsetof (struct cpuinfo_ia64, pgd_quick));
+ DEFINE(IA64_CPUINFO_KSOFTIRQD_OFFSET, offsetof (struct cpuinfo_ia64, ksoftirqd));
//DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock));
return 1;
}
-extern void pal_emulator_static (void);
+extern struct ia64_pal_retval pal_emulator_static (unsigned long);
/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
*/
status = 0;
if (index == SAL_FREQ_BASE) {
- switch (in1) {
+ if (!running_on_sim)
+ status = ia64_sal_freq_base(in1,&r9,&r10);
+ else switch (in1) {
case SAL_FREQ_BASE_PLATFORM:
r9 = 200000000;
break;
case SAL_FREQ_BASE_INTERVAL_TIMER:
- /*
- * Is this supposed to be the cr.itc frequency
- * or something platform specific? The SAL
- * doc ain't exactly clear on this...
- */
r9 = 700000000;
break;
return ((struct sal_ret_values) {status, r9, r10, r11});
}
+struct ia64_pal_retval
+xen_pal_emulator(unsigned long index, unsigned long in1,
+ unsigned long in2, unsigned long in3)
+{
+ long r9 = 0;
+ long r10 = 0;
+ long r11 = 0;
+ long status = -1;
+
+ if (running_on_sim) return pal_emulator_static(index);
+ if (index >= PAL_COPY_PAL) {
+ printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
+ index);
+ }
+ else switch (index) {
+ case PAL_MEM_ATTRIB:
+ status = ia64_pal_mem_attrib(&r9);
+ break;
+ case PAL_FREQ_BASE:
+ status = ia64_pal_freq_base(&r9);
+ break;
+ case PAL_PROC_GET_FEATURES:
+ status = ia64_pal_proc_get_features(&r9,&r10,&r11);
+ break;
+ case PAL_BUS_GET_FEATURES:
+ status = ia64_pal_bus_get_features(&r9,&r10,&r11);
+ break;
+ case PAL_FREQ_RATIOS:
+ status = ia64_pal_freq_ratios(&r9,&r10,&r11);
+ break;
+ case PAL_PTCE_INFO:
+ status = ia64_get_ptce(&r9);
+ break;
+ case PAL_VERSION:
+ status = ia64_pal_version(&r9,&r10);
+ break;
+ case PAL_VM_PAGE_SIZE:
+ status = ia64_pal_vm_page_size(&r9,&r10);
+ break;
+ case PAL_DEBUG_INFO:
+ status = ia64_pal_debug_info(&r9,&r10);
+ break;
+ case PAL_CACHE_SUMMARY:
+ status = ia64_pal_cache_summary(&r9,&r10);
+ break;
+ case PAL_VM_SUMMARY:
+ status = ia64_pal_vm_summary(&r9,&r10);
+ break;
+ case PAL_RSE_INFO:
+ status = ia64_pal_rse_info(&r9,&r10);
+ break;
+ case PAL_VM_INFO:
+ status = ia64_pal_vm_info(in1,in2,&r9,&r10);
+ break;
+ case PAL_REGISTER_INFO:
+ status = ia64_pal_register_info(in1,&r9,&r10);
+ break;
+ case PAL_CACHE_FLUSH:
+ return pal_emulator_static(index); /* FIXME */
+ break;
+ case PAL_PERF_MON_INFO:
+ {
+ unsigned long pm_buffer[16];
+ status = ia64_pal_perf_mon_info(pm_buffer,&r9);
+ if (status != 0) break;
+ if (copy_to_user((void __user *)in1,pm_buffer,128))
+ printk("xen_pal_emulator: PAL_PERF_MON_INFO "
+ "can't copy to user!!!!\n");
+ }
+ break;
+ case PAL_CACHE_INFO:
+ {
+ pal_cache_config_info_t ci;
+ status = ia64_pal_cache_config_info(in1,in2,&ci);
+ if (status != 0) break;
+ r9 = ci.pcci_info_1.pcci1_data;
+ r10 = ci.pcci_info_2.pcci2_data;
+ }
+ break;
+ case PAL_VM_TR_READ: /* FIXME: vcpu_get_tr?? */
+ break;
+ case PAL_HALT_INFO: /* inappropriate info for guest? */
+ break;
+ default:
+ printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
+ index);
+ break;
+ }
+ return ((struct ia64_pal_retval) {status, r9, r10, r11});
+}
#define NFUNCPTRS 20
#include <asm/dom_fw.h>
extern unsigned long translate_domain_mpaddr(unsigned long);
-extern struct ia64_sal_retval pal_emulator_static(UINT64);
+extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
unsigned long idle_when_pending = 0;
{
struct vcpu *v = (struct domain *) current;
struct ia64_sal_retval x;
+ struct ia64_pal_retval y;
unsigned long *tv, *tc;
int pi;
// in the idle loop, this should resolve it
v->vcpu_info->arch.pending_interruption = 1;
#endif
- x = pal_emulator_static(regs->r28);
if (regs->r28 == PAL_HALT_LIGHT) {
#define SPURIOUS_VECTOR 15
pi = vcpu_check_pending_interrupts(v);
}
//break;
}
- regs->r8 = x.status; regs->r9 = x.v0;
- regs->r10 = x.v1; regs->r11 = x.v2;
+ else if (regs->r28 >= PAL_COPY_PAL) { /* FIXME */
+ printf("stacked PAL hypercalls not supported\n");
+ regs->r8 = -1;
+ break;
+ }
+ else y = xen_pal_emulator(regs->r28,regs->r29,
+ regs->r30,regs->r31);
+ regs->r8 = y.status; regs->r9 = y.v0;
+ regs->r10 = y.v1; regs->r11 = y.v2;
break;
case FW_HYPERCALL_SAL_CALL:
x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
;;
#ifdef XEN
mov r30=cr.ivr // pass cr.ivr as first arg
- // FIXME: this is a hack... use cpuinfo.pgd_quick because its
+ // FIXME: this is a hack... use cpuinfo.ksoftirqd because its
// not used anywhere else and we need a place to stash ivr and
// there's no registers available unused by SAVE_MIN/REST
- movl r29=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
+ movl r29=(PERCPU_ADDR)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
st8 [r29]=r30;;
movl r28=slow_interrupt;;
mov r29=rp;;
;;
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
#ifdef XEN
- movl out0=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
+ movl out0=(PERCPU_ADDR)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
ld8 out0=[out0];;
#else
mov out0=cr.ivr // pass cr.ivr as first arg
#define itir_mask(itir) (~((1UL << itir_ps(itir)) - 1))
unsigned long vhpt_translate_count = 0;
+int in_vcpu_tpa = 0;
IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir)
{
ia64_rr rr;
if (!(address >> 61)) {
- if (!PSCB(vcpu,metaphysical_mode))
+ if (!PSCB(vcpu,metaphysical_mode)) {
+ REGS *regs = vcpu_regs(vcpu);
+ unsigned long viip = PSCB(vcpu,iip);
+ unsigned long vipsr = PSCB(vcpu,ipsr);
+ unsigned long iip = regs->cr_iip;
+ unsigned long ipsr = regs->cr_ipsr;
+#if 0
+ printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p\n", address, viip, vipsr, iip, ipsr);
+ if (in_vcpu_tpa) printk("vcpu_translate called from vcpu_tpa\n");
+ while(1);
panic_domain(0,"vcpu_translate: bad address %p\n", address);
+#endif
+ printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p continuing\n", address, viip, vipsr, iip, ipsr);
+ }
*pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
*itir = PAGE_SHIFT << 2;
/* check 1-entry TLB */
if ((trp = match_dtlb(vcpu,address))) {
dtlb_translate_count++;
+if (!in_vcpu_tpa) printf("vcpu_translate: found in vdtlb\n");
*pteval = trp->page_flags;
*itir = trp->itir;
return IA64_NO_FAULT;
UINT64 pteval, itir, mask;
IA64FAULT fault;
+in_vcpu_tpa=1;
fault = vcpu_translate(vcpu, vadr, 1, &pteval, &itir);
+in_vcpu_tpa=0;
if (fault == IA64_NO_FAULT)
{
mask = itir_mask(itir);